////////////////////////////////////////////////////////////////////
// Programme d'extraction/insertion de coordonnées de Chrono Cross
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
// Nemesis pour Terminus Traduction (tt_nemesis@yahoo.fr)
// Date de création :		11/08/03
// Dernière modification :	17/08/03
////////////////////////////////////////////////////////////////////

// Entete
#include "Coordonnees.h"

// Noms des fichiers
char *Coord_Elmts[COORD_ELMTS_NB];

/*------------------------------------------------------------------
  Initialisation des fichiers de coordonnées
--------------------------------------------------------------------
 <- dir : chemin partiel des infos à charger
 <- fich : fichier d'infos à charger
------------------------------------------------------------------*/
void Coord_Infos (char *dir, char *fich)
{
	// Fichier des infos
	FILE *infos_f;
	// Nom de l'iso (chemin)
	char infos_nom[COORD_NOM_MAX];
	// Ligne
	char ligne[COORD_LIGNE_MAX];
	// Informations
	char description[COORD_DESC_MAX];
	unsigned int num;
	// Nombre de champs d'infos

	// Ouverture du fichier des infos principales
	sprintf(infos_nom,"%s%s%s%s.%s",
		DIR_INFOS,DIR_INFOS_COORD,dir,fich,EXT_INFOS);
	infos_f=fopen(infos_nom,"rb");

	if (infos_f==NULL)
		Main_Message_S("Pas d'infos...","",OK);
	else {
		// Récupération des noms de fichiers
		while (fgets(ligne,COORD_LIGNE_MAX,infos_f)!=NULL)
			// Cas d'un commentaire ou d'un blanc
			if (ligne[0]!=COMMENT) {
				sscanf(ligne,"%03d=%s",&num,description);
				Coord_Elmts[num]=strdup(description);
			}
		// Fermeture du fichier des infos
		fclose(infos_f);
	}
}


/*------------------------------------------------------------------
  Réinitialisation des fichiers de coordonnées à NULL
------------------------------------------------------------------*/
void Coord_Infos_Vide (void)
{
	int e;

	for(e=0;e<COORD_ELMTS_NB;e++)
		if (Coord_Elmts[e]!=NULL) {
			free(Coord_Elmts[e]);
			Coord_Elmts[e]=NULL;
		}
}

/*------------------------------------------------------------------
  Copie d'octets en pseudo-hexa
--------------------------------------------------------------------
 <- nb : nombre d'octets à copier
 <- in_f : fichier d'entrée
 <- out_f : fichier de sortie
------------------------------------------------------------------*/
void Coord_Copie_16 (int nb, FILE *in_f, FILE *out_f)
{
	int o;
	unsigned _int8 c;

	fputc(COORD_16_O,out_f);
	for(o=0;o<nb;o++) {
		c=fgetc(in_f);
		fprintf(out_f,"%02x",c);
	}
	fputc(COORD_16_F,out_f);
}

/*------------------------------------------------------------------
  Copie d'octets en décimal
--------------------------------------------------------------------
 <- nb : nombre d'octets à copier
 <- in_f : fichier d'entrée
 <- out_f : fichier de sortie
------------------------------------------------------------------*/
void Coord_Copie_10 (FILE *in_f, FILE *out_f)
{
	unsigned _int8 c;

	c=fgetc(in_f);
	fprintf(out_f,"%c%03d.",COORD_10_O,c);
	c=fgetc(in_f);
	fprintf(out_f,"%03d%c",c,COORD_10_F);
}

/*------------------------------------------------------------------
  Dump de coordonnées (coordonnées)
--------------------------------------------------------------------
 <- entree : dossier|fichier contenant les coordonnées à dumper
------------------------------------------------------------------*/
void Coord_Dump (char *entree)
{
	// Fichier de coordonnées à dumper
	FILE *coord_f;
	char coord_nom[COORD_NOM_MAX];
	char *coord_nom2;
	char coord_nom_complet[COORD_NOM_MAX];
	// Fichier de sortie
	FILE *out_f;
	// Dossier complet
	char dossier[COORD_NOM_MAX];
	// Adresses des éléments
	_int16 adresses[COORD_ELMTS_NB];
	int adresses_nb=-1;
	// Index des éléments
	int e;
	// Fichier et dossier
	char *dir;
	char *fich;
	// Composantes
	_int32 composantes;
	// Index des composantes
	int c;

	// Décomposition dossier/fichiers
	dir=strtok(entree,SEPARATEUR);
	if (dir[0]==NEUTRE)
		dir[0]=0;
	fich=strtok(NULL,SEPARATEUR);

	Main_Message_S("Dump des coordonnees %s...",fich,OK);

	// Recherche du fichier de coordonnées
	sprintf(coord_nom,"%04d",atoi(fich));
	sprintf(dossier,"%s%s",DIR_FICH_IN,dir);
	Fichier_Cherche(dossier,coord_nom,EXT_COORD,&coord_nom2);
	sprintf(coord_nom_complet,"%s%s",dossier,coord_nom2);
	// Ouverture du fichier de coordonnées
	coord_f=fopen(coord_nom_complet,"rb");

	// Fichier existant ?
	if (coord_f==NULL)
		Main_Message_S("Impossible d'ouvrir les coordonnees.\n","",ER);
	else {
		// Chargement des informations de coordonnées
		Coord_Infos(dir,fich);
		// Ouverture du fichier en clair
		strcpy(&coord_nom_complet[strlen(coord_nom_complet)-3],EXT_TXT);
		out_f=fopen(coord_nom_complet,"w");
		// Copie de l'entête
		Coord_Copie_16(COORD_ENTETE,coord_f,out_f);
		fputc('\n',out_f);
		// Chargement des adresses
		do {
			adresses_nb++;
			fread(&adresses[adresses_nb],sizeof(_int16),1,coord_f);
		} while(ftell(coord_f)<adresses[0]);
		// Ecriture du nombre d'éléments
		fprintf(out_f,"<%03d>\n",adresses_nb);
		// Récupérations des coordonnées
		for(e=0;e<=adresses_nb;e++) {
			// Placement dans le fichier compacté
			if (adresses[e]!=0) {
				fseek(coord_f,adresses[e],SEEK_SET);
				// Lecture du nombre de composantes
				fread(&composantes,sizeof(_int32),1,coord_f);
			} else
				composantes=0;
			// Affichage des informations de l'élément
			if (Coord_Elmts[e]!=NULL)
				fprintf(out_f,"%03d (%03d) - %s\n",
					e,composantes,Coord_Elmts[e]);
			else
				fprintf(out_f,"%03d (%03d) - ?\n",
					e,composantes);
			// Extraction des composantes
			for(c=0;c<composantes;c++)
			{
				fputc(' ',out_f);
				// Coordonnées cible
				Coord_Copie_10(coord_f,out_f);
				// Décalage de l'image
				Coord_Copie_10(coord_f,out_f);
				// Coordonnées source
				Coord_Copie_10(coord_f,out_f);
				// Image
				Coord_Copie_16(2,coord_f,out_f);
				// Dimensions
				Coord_Copie_10(coord_f,out_f);
				Coord_Copie_16(2,coord_f,out_f);
				fputc('\n',out_f);
			}
			// Ligne de séparation
			fprintf(out_f,"--------------------------"
				"-----------------------\n");
		}
		// Fermeture des coordonnées
		fclose(coord_f);
		fclose(out_f);
		// Nettoyage des infos coordonnées
		Coord_Infos_Vide();
	}

	Main_OK();
}

/*------------------------------------------------------------------
  Passage à la ligne suivante
--------------------------------------------------------------------
 <- fichier : fichier à traiter
------------------------------------------------------------------*/
void Coord_Fin_Ligne(FILE *fich) {
	char ligne[COORD_LIGNE_MAX];
	
	fgets(ligne,COORD_LIGNE_MAX,fich);
}

/*------------------------------------------------------------------
  Copie d'octets en pseudo-hexa
--------------------------------------------------------------------
 <- nb : nombre d'octets à copier
 <- in_f : fichier d'entrée
 <- out_f : fichier de sortie
------------------------------------------------------------------*/
void Coord_Rein_16 (int nb, FILE *in_f, FILE *out_f)
{
	int o;
	unsigned _int8 c;

	fgetc(in_f);
	for(o=0;o<nb;o++) {
		fscanf(in_f,"%02x",&c);
		fputc(c,out_f);
	}
	fgetc(in_f);
}

/*------------------------------------------------------------------
  Copie d'octets en décimal
--------------------------------------------------------------------
 <- nb : nombre d'octets à copier
 <- in_f : fichier d'entrée
 <- out_f : fichier de sortie
------------------------------------------------------------------*/
void Coord_Rein_10 (FILE *in_f, FILE *out_f)
{
	unsigned _int8 c;

	fgetc(in_f);
	fscanf(in_f,"%03d",&c);
	fputc(c,out_f);
	fscanf(in_f,".%03d",&c);
	fputc(c,out_f);
	fgetc(in_f);
}

/*------------------------------------------------------------------
  Réinsertion du Coord (coordonnées)
--------------------------------------------------------------------
 <- entree : dossier|fichier contenant les coordonnées à réinsérer
------------------------------------------------------------------*/
void Coord_Rein (char *entree)
{
	// Fichier des coordonnées à réinsérer
	FILE *in_f;
	char coord_nom[COORD_NOM_MAX];
	char *coord_nom2;
	char coord_nom_complet[COORD_NOM_MAX];
	// Fichier de sortie
	FILE *coord_f;
	// Dossier complet
	char dossier[COORD_NOM_MAX];
	// Adresses des éléments
	_int16 adresses[COORD_ELMTS_NB];
	int adresses_nb=-1;
	// Index des éléments
	int e;
	// Fichier et dossier
	char *dir;
	char *fich;
	// Numero d'élément (inutile)
	int num;
	// Composantes
	_int32 composantes;
	// Index des composantes
	int c;
	// Position dans le fichier
	_int16 pos;

	// Décomposition dossier/fichiers
	dir=strtok(entree,SEPARATEUR);
	if (dir[0]==NEUTRE)
		dir[0]=0;
	fich=strtok(NULL,SEPARATEUR);

	Main_Message_S("Reinsertion du coord %s...",fich,OK);

	// Recherche du fichier en clair
	sprintf(coord_nom,"%04d",atoi(fich));
	sprintf(dossier,"%s%s",DIR_FICH_OUT,dir);
	Fichier_Cherche(dossier,coord_nom,EXT_TXT,&coord_nom2);
	sprintf(coord_nom_complet,"%s%s",dossier,coord_nom2);
	// Ouverture du fichier en clair
	in_f=fopen(coord_nom_complet,"r");

	// Fichier existant ?
	if (in_f==NULL)
		Main_Message_S("Impossible d'ouvrir le coord.\n","",ER);
	else {
		// Ouverture du fichier de coordonnées
		strcpy(&coord_nom_complet[strlen(coord_nom_complet)-3],EXT_COORD);
		coord_f=fopen(coord_nom_complet,"wb");
		// Copie de l'entête
		Coord_Rein_16(COORD_ENTETE,in_f,coord_f);
		Coord_Fin_Ligne(in_f);
		// Lecture du nombre d'éléments
		fgetc(in_f);
		fscanf(in_f,"%03d",&adresses_nb);
		Coord_Fin_Ligne(in_f);
		// Calcul de la première adresse
		pos=COORD_ENTETE+(adresses_nb+1)*sizeof(_int16);
		adresses[0]=pos;
		// Placement dans le fichier final
		fseek(coord_f,pos,SEEK_SET);
		// Réinsertion des coordonnées
		for(e=0;e<=adresses_nb;e++) {
			// Nombre de composantes et écriture
			fscanf(in_f,"%03d (%03d)",&num,&composantes);
			Coord_Fin_Ligne(in_f);
			// Cas d'adresse nulle
			if (e!=adresses_nb || composantes!=0) {
				pos+=(_int16)(COORD_INFO*composantes)+sizeof(_int32);
				fwrite(&composantes,sizeof(_int32),1,coord_f);
				adresses[e+1]=pos;
			}
			if (composantes==0)
				adresses[e]=0;
			// Réinsertion des composantes
			for(c=0;c<composantes;c++)
			{
				// Caractère blanc
				fgetc(in_f);
				// Coordonnées cible
				Coord_Rein_10(in_f,coord_f);
				// Décalage de l'image
				Coord_Rein_10(in_f,coord_f);
				// Coordonnées source
				Coord_Rein_10(in_f,coord_f);
				// Image
				Coord_Rein_16(2,in_f,coord_f);
				// Dimensions
				Coord_Rein_10(in_f,coord_f);
				Coord_Rein_16(2,in_f,coord_f);
				Coord_Fin_Ligne(in_f);
			}
			// Ligne de tirets
			Coord_Fin_Ligne(in_f);
		}
		// Fermeture des coordonnées
		fclose(in_f);
		fclose(coord_f);
		// Reouverture des coordonnées
		coord_f=fopen(coord_nom_complet,"r+b");
		// Placement puis écriture des adresses
		fseek(coord_f,COORD_ENTETE,SEEK_SET);
		for(e=0;e<=adresses_nb;e++)
			fwrite(&adresses[e],sizeof(_int16),1,coord_f);
		// Refermeture des coordonnées
		fclose(coord_f);
	}

	Main_OK();
}